from datetime import datetime
import time
from django.http import JsonResponse
from rest_framework.views import APIView
from .models import coffee, fields, templates
from utils.response import APIResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
import os,uuid,json
from django.core.exceptions import ObjectDoesNotExist, ValidationError

class CoffeeListView(APIView):
    def get(self, request):
        coffees = coffee.objects.filter(status=1)
        data = [{
            'id': c.id,
            'name': c.name,
            'price': c.price,
            'desc': c.desc
        } for c in coffees]
        return APIResponse(data=data)

    def post(self, request):
        name = request.data.get('name')
        price = request.data.get('price')
        desc = request.data.get('desc')
        
        if not all([name, price]):
            return APIResponse(code=400, message='缺少必要参数')
            
        coffee_obj = coffee.objects.create(
            name=name,
            price=price,
            desc=desc or '',
            status=1
        )
        return APIResponse(message='创建成功', data={'id': coffee_obj.id})
    
class CoffeeDetailView(APIView):
    def get(self, request, pk):
        try:
            coffee_obj = coffee.objects.get(pk=pk, status=1)
            data = {
                'id': coffee_obj.id,
                'name': coffee_obj.name,
                'price': coffee_obj.price,
                'desc': coffee_obj.desc
            }
            return APIResponse(data=data)
        except coffee.DoesNotExist:
            return APIResponse(code=404, message='咖啡不存在')
    
    def put(self, request, pk):
        try:
            coffee_obj = coffee.objects.get(pk=pk, status=1)
            name = request.data.get('name', coffee_obj.name)
            price = request.data.get('price', coffee_obj.price)
            desc = request.data.get('desc', coffee_obj.desc)
            
            coffee_obj.name = name
            coffee_obj.price = price
            coffee_obj.desc = desc
            coffee_obj.save()
            
            return APIResponse(message='更新成功')
        except coffee.DoesNotExist:
            return APIResponse(code=404, message='咖啡不存在')
    
    def delete(self, request, pk):
        try:
            coffee_obj = coffee.objects.get(pk=pk, status=1)
            coffee_obj.status = 0
            coffee_obj.save()
            return APIResponse(message='删除成功')
        except coffee.DoesNotExist:
            return APIResponse(code=404, message='咖啡不存在')

@method_decorator(csrf_exempt, name='dispatch')
class CoffeeUploaderView(APIView):
   def post(self, request):
        
        if 'file' not in request.FILES:
            return JsonResponse({'error': 'No file provided'}, status=400)
        
        uploaded_file = request.FILES['file']
        
        # 处理文件名
        original_name = uploaded_file.name
        ext = os.path.splitext(original_name)[1]

        new_filename = f"{uuid.uuid4().hex}{ext}"
        upload_dir = os.path.join(settings.MEDIA_ROOT, 'uploads')
        save_path = os.path.join(upload_dir, new_filename)
        
        # 确保目录存在
        os.makedirs(upload_dir, exist_ok=True)
        
        try:
            # 保存文件
            with open(save_path, 'wb+') as destination:
                for chunk in uploaded_file.chunks():
                    destination.write(chunk)
            
            # 验证文件是否保存成功
            if not os.path.exists(save_path):
                return JsonResponse({'error': 'File save failed'}, status=500)
            
            file_size = os.path.getsize(save_path)
            
            # 构建访问 URL
            file_url = os.path.join(settings.MEDIA_ROOT,'uploads/',new_filename)
            
            return JsonResponse({
                'status': 'success',
                'original_name': original_name,
                'saved_name': new_filename,
                'file_url': file_url,
                'size': file_size
            })
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)

REQUIRED_FIELDS = ['name', 'field_type']  # 更换 type 为 field_type 避免关键字冲突
ALL_FIELDS = ['name', 'field_type', 'value', 'required', 'min', 'max',
              'placeholder', 'show_count', 'status']

class CoffeeFieldsView(APIView):
    """
    咖啡字段管理视图，处理字段的增删改查操作

    支持GET、POST、PUT、DELETE方法
    - GET: 获取所有字段信息
    - POST: 创建新字段
    - PUT: 更新指定ID的字段
    - DELETE: 删除指定ID的字段
    """
    def get(self, request):
        """
        获取所有字段信息

        参数:
            request (Request): DRF请求对象

        返回:
            APIResponse: 包含所有字段数据的响应对象
        """
        data = list(fields.objects.all().values().order_by('-id'))
        for item in data:
            try:    
                item['value'] = json.loads(item['value'])
            except json.JSONDecodeError:
                pass
        return APIResponse(data=list(data))
    
    # 获取允许使用的字段列表
    def get_fields_list(request):
        data = list(fields.objects.all().filter(status=1).values('id','name','field_type','status').order_by('-id'))
        return APIResponse(data=data)
    
    def post(self, request):
        """
        创建新字段

        参数:
            request (Request): DRF请求对象，包含创建字段所需的数据

        返回:
            APIResponse: 操作结果的响应

        异常:
            400: 缺少必要参数或验证失败
            500: 服务器内部错误
        """
        data = request.data
        if not all(data.get(field) for field in REQUIRED_FIELDS):
            return APIResponse(code=400, message='缺少必要参数')

        try:
            #验证字段
            validated_data = self._validate_and_filter_fields(data)
            # 处理 value 字段 存储json格式
            if 'value' in data:
                validated_data['value'] = json.dumps(data['value'])
            #存储字段信息
            fields_obj = fields.objects.create(**validated_data)
            # 返回json格式数据
            return APIResponse(message='创建成功', data={'id': fields_obj.id})
        except ValidationError as ve:
            return APIResponse(code=400, message=str(ve))
        except Exception as e:
            return APIResponse(code=500, message=str(e))
        

    def put(self, request, pk):
        """
        更新指定ID的字段

        参数:
            request (Request): DRF请求对象，包含更新数据
            pk (int): 要更新的字段主键ID

        返回:
            APIResponse: 操作结果的响应

        异常:
            404: 指定ID的字段不存在
            400: 验证失败
            500: 服务器内部错误
        """
        try:
            fields_obj = fields.objects.get(pk=pk)
            validated_data = self._validate_and_filter_fields(request.data, is_update=True)
            if 'value' in validated_data:
                validated_data['value'] = json.dumps(validated_data['value'])
                
            for key, value in validated_data.items():
                setattr(fields_obj, key, value)
            fields_obj.save()
            return APIResponse(message='更新成功')
        except ObjectDoesNotExist:
            return APIResponse(code=404, message='字段不存在')
        except ValidationError as ve:
            return APIResponse(code=400, message=str(ve))
        except Exception as e:
            return APIResponse(code=500, message="服务器内部错误")
    
    def delete(self, request, pk):
        """
        删除指定ID的字段

        参数:
            request (Request): DRF请求对象
            pk (int): 要删除的字段主键ID

        返回:
            APIResponse: 操作结果的响应

        异常:
            404: 指定ID的字段不存在
            500: 服务器内部错误
        """
        try:
            fields_obj = fields.objects.get(pk=pk)
            fields_obj.delete()
            return APIResponse(message='删除成功')
        except ObjectDoesNotExist:
            return APIResponse(code=404, message='字段不存在')
        except Exception as e:
            return APIResponse(code=500, message="服务器内部错误")
        
    def _validate_and_filter_fields(self, data, is_update=False):
        """
        对字段数据进行验证和过滤，确保数据符合预期格式和约束条件
        
        该方法会遍历所有定义的字段，对每个字段进行类型检查和转换：
        - field_type 字段不能为空
        - required 和 showCount 字段必须是布尔值
        - min 和 max 字段必须是数字类型
        
        参数:
            data (dict): 包含待验证和过滤的字段数据字典
            is_update (bool): 指示当前操作是否为更新，默认为False
            
        返回:
            dict: 包含验证通过且适当转换后的字段字典
            
        异常:
            ValidationError: 当任何字段验证失败时抛出，包含具体错误信息
            
        特殊处理:
            - 对于更新操作(is_update=True)，仅处理存在于data中的字段
            - 对于布尔值字段，尝试将非布尔值转换为布尔值
            - 对于数值字段(min/max)，尝试将非数字值转换为浮点数
        """
        result = {}
        for field in ALL_FIELDS:
            value = data.get(field)
            if not is_update or (field in data):  # 更新时仅当字段存在才更新
                if field == 'field_type':
                    if not value:
                        raise ValidationError("字段类型不能为空")
                elif field in ['required', 'showCount']:
                    if not isinstance(value, bool):
                        try:
                            value = bool(value)
                        except ValueError:
                            raise ValidationError(f"{field} 必须为布尔值")
                elif field in ['min', 'max']:
                    if value is not None and not isinstance(value, (int, float)):
                        try:
                            value = float(value)
                        except ValueError:
                            raise ValidationError(f"{field} 必须为数字")
                result[field] = value
        return result

class CoffeeTemplateView(APIView):
    """
    咖啡模板管理
    """
    def get(self, request):
        """
        获取所有咖啡模板信息

        参数:
            request (Request): DRF请求对象

        返回:
            APIResponse: 包含咖啡模板信息的响应

        异常:
            500: 获取数据失败
        """
        try:
            data = templates.objects.all().order_by('-id').values(
                'id', 'name', 'description', 'fields','create_time', 'status'
            )
            for item in data:
                try:
                    # 解析 fields 字段
                    if isinstance(item['fields'], str):
                        field_ids = json.loads(item['fields'])
                    else:
                        field_ids = item['fields'] = []
                    if item['create_time']:
                        try:
                            item['create_time'] = datetime.fromtimestamp(item['create_time']).strftime('%Y-%m-%d %H:%M:%S')
                        except (TypeError,OSError):
                            item['create_time'] = None
                    # 如果存在字段 ID，则查询完整字段信息
                    if field_ids:
                        full_fields = list(fields.objects.filter(id__in=field_ids).values('id', 'field_type', 'name'))
                        item['full_fields'] = full_fields
                    else:
                        item['full_fields'] = []
                except (json.JSONDecodeError, TypeError):
                    item['fields'] = []
                    item['full_fields'] = []
            return APIResponse(data=list(data))
        except Exception as e:
            return APIResponse(code=500, message=str(e))

    def post(self, request):
        """
        创建新的咖啡模板

        参数:
            request (Request): DRF请求对象，包含新的咖啡模板数据

        返回:
            APIResponse: 创建结果响应

        异常:
            400: 验证失败
            500: 创建失败
        """
        try:
            validated_data = self._validate_and_filter_templates(request.data)
            templates.objects.create(**validated_data)
            return APIResponse(message='创建成功')
        except Exception as e:
            return APIResponse(code=500, message=str(e))
        
    def put(self, request, pk):
        """更新咖啡模板

        参数:
            request (Request): DRF请求对象，包含新的咖啡模板数据
            kwargs (dict): URL参数，包含模板ID

        返回:
            APIResponse: 更新结果响应

        异常:
            400: 验证失败
            500: 更新失败
        """
        try:
            template_obj = templates.objects.get(pk=pk)
            data = request.data
            validate_data = self._validate_and_filter_templates(data, True)
           
            for key, value in validate_data.items():
                setattr(template_obj, key, value)
            template_obj.save()
            return APIResponse(message='更新成功')
        except Exception as e:
            return APIResponse(code=500, message=str(e))

    def delete(self, request,pk):
        """
        删除模板
        """
        try:
            template_obj = templates.objects.filter(id=pk).first()
            if not template_obj:
                return APIResponse(code=400, message='模板不存在')
            template_obj.delete()
            return APIResponse(message='删除成功')
        except Exception as e:
            return APIResponse(code=500, message=str(e))

    #数据校验
    def _validate_and_filter_templates(self, data, is_update=False):
        fields = ['id', 'name', 'description', 'fields','create_time','status']
        result = {}
        for field in fields:
            value = data.get(field)
            if not is_update or (field in data):  # 更新时仅当字段存在才更新
                result[field] = value
                if field == 'fields':
                    result[field] = json.dumps(value)
                if not is_update:
                    result['create_time'] = int(time.time())
                    result.pop('id', None)
        return result